package cn.bluethink.eguan.core.service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;

import cn.bluethink.eguan.core.entity.ActionEntity;
import cn.bluethink.eguan.core.entity.EgActionEntity;
import cn.bluethink.eguan.core.mapper.EgActionMapper;
import cn.bluethink.eguan.filter.ActionFilter;
import cn.bluethink.eguan.model.core.EgAction;
import cn.bluethink.eguan.model.core.EgActionFlag;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgObject;
import cn.bluethink.eguan.model.core.EgPurview;
import cn.bluethink.eguan.model.core.EgRole;
import cn.bluethink.eguan.model.core.EgTavern;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.result.PageInfo;
import cn.bluethink.eguan.utils.IdMakerUtils;

/**
 * 用户操作对象的动作业务层
 * 
 * @author 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.2.0
 * @brief 驿馆+（EGUAN）
 * @note 修订历史： 1、wanglei于2018/11/09设计并构建初始版本v0.2.0
 */
@Service
public class EgActionService {

    @Autowired
    private EgActionMapper actionMapper;

    @Autowired
    private EgPosObjectService posObjService;

    @Autowired
    private EgStaffService staffService;

    @Autowired
    private EgTavernService tavernService;

    @Autowired
    private EgUserService userService;

    private IdMakerUtils idMakerUtil = new IdMakerUtils();

    /**
     * 创建动作动态(不暴露接口)
     * 
     * @param atid
     * @param obj
     * @param result
     * @param rcontent
     * @param pos
     * @param uid
     * @param actFlag
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean create(Integer atid, EgObject obj, EgObject result, String rcontent, EgObject pos, Long uid,
            Integer actFlag) throws Exception {
        EgActionEntity entity = new EgActionEntity(atid, obj, result, rcontent, pos, uid, actFlag);
        // 设置动作ID
        entity.setAid(idMakerUtil.nextId());
        int insertCount = actionMapper.insertSelective(entity);
        return insertCount > 0 ? true : false;
    }

    /**
     * 过滤查询动作
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    public PageInfo<EgAction> query(ActionFilter filter) throws Exception {
        Integer pageNum = filter.getPageNum() == null ? 1 : filter.getPageNum();
        Integer pageSize = filter.getPageSize() == null ? 20 : filter.getPageSize();
        // 构造查询条件
        String whereSql = buildQuerySql(filter);
        // 返回结果
        List<EgAction> result = new ArrayList<>();
        List<ActionEntity> entities = new ArrayList<>();
        // 判断whereSql不为空，根据条件查询
        if (StringUtils.isNotBlank(whereSql)) {
            // 分页
            PageHelper.startPage(pageNum, pageSize);
            entities = actionMapper.query(whereSql);
        }
        PageInfo<ActionEntity> oldPageInfo = new PageInfo<>(entities);
        if (entities != null && entities.size() > 0) {
            result = entities.stream().map(e -> e.createEgAction()).collect(Collectors.toList());
        }
        return new PageInfo<>(result, oldPageInfo);
    }

    /**
     * 根据过滤条件构建查询条件
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    private String buildQuerySql(ActionFilter filter) throws Exception {

        String whereSql = "";
        List<String> whereSqlList = new ArrayList<>();
        // 声明过滤条件
        Long id = filter.getId() == null ? 0 : filter.getId();
        Boolean buid = filter.getBuid() == null ? false : filter.getBuid();
        Integer otype = filter.getOtype() == null ? EgOType.OKR_TASK : filter.getOtype();

        whereSqlList.add(" 1 = 1");
        // 只查询操作记录
        whereSqlList.add("(ea.act_flag & " + EgActionFlag.OPREATE + ")> 0 ");
        // 根据被操作的对象查询操作记录
        if (!buid && id > 0 && otype > 0) {
            // 附带查询其上传的文件以及删除的文件
            String oidsql = " ((ea.oid = " + id + " and ea.otype = " + otype + ") or (ea.roid = " + id
                    + " and ea.rtype = " + otype + "))";
            // 如果查询工作任务，附带查询其 检查项, 不查询评论工作任务和删除工作任务(即不查询动态)
            if (otype.equals(EgOType.OKR_TASK)) {
                oidsql += "or (ea.otype = " + EgOType.CHECK_ITEM
                        + " and ea.oid in ( select krid from eg_taskkr where tid = " + id + "))";
                oidsql = " (" + oidsql + ")";
            }
            whereSqlList.add(oidsql);
        }
        // 设置查询条件AND连接符
        if (whereSqlList.size() > 0) {
            whereSql += String.join(" AND ", whereSqlList);
        }
        // 排序规则
        whereSql += " ORDER BY ea.ctime DESC";
        return whereSql;
    }

    /**
     * 过滤查询动态 1. 根据动态发生的位置对象的ID过滤查询 2. 根据成员的ID过滤查询
     * 
     * @param filter
     * @param uid
     * @return
     * @throws Exception
     */
    public PageInfo<EgAction> dynamic(ActionFilter filter, Long uid) throws Exception {
        Integer pageNum = filter.getPageNum() == null ? 1 : filter.getPageNum();
        Integer pageSize = filter.getPageSize() == null ? 20 : filter.getPageSize();
        // 构造查询条件
        String whereSql = buildQueryDynamicSql(filter, uid);
        // 返回结果
        List<EgAction> result = new ArrayList<>();
        List<ActionEntity> entities = new ArrayList<>();
        // 判断whereSql不为空，根据条件查询
        if (StringUtils.isNotBlank(whereSql)) {
            // 分页
            PageHelper.startPage(pageNum, pageSize);
            entities = actionMapper.query(whereSql);
        }
        PageInfo<ActionEntity> oldPageInfo = new PageInfo<>(entities);
        for (ActionEntity entity : entities) {
            EgAction action = entity.createEgAction();
            // 获取位置的信息
            EgObject pos = posObjService.pos(entity.getPosOtype(), entity.getPosOid());
            if (pos != null) {
                action.setPos(new EgObject(pos.getId(), pos.getName(), null));
            } else {
                action.setPos(null);
            }
            result.add(action);
        }
        return new PageInfo<>(result, oldPageInfo);
    }

    /**
     * 构造查询动态的sql语句
     * 
     * @param filter
     * @param uid
     * @return
     * @throws Exception
     */
    private String buildQueryDynamicSql(ActionFilter filter, Long uid) throws Exception {

        String whereSql = "";
        List<String> whereSqlList = new ArrayList<>();
        // 声明过滤条件
        Long id = filter.getId() == null ? 0 : filter.getId();
        Boolean buid = filter.getBuid() == null ? false : filter.getBuid();
        EgObject pos = filter.getPos() == null ? null : filter.getPos();
        Integer posOtype = null;
        Long posId = null;
        // 获取当前登录用户的权限
        EgRole role = userService.mypurview(uid);
        // 获取用户信息
        EgUser user = userService.getUser(uid, false);
        // 获取用户位置对象类型ID，以及用户位置对象ID，
        Integer otype = user.getPos().getType().getOtid();
        Long oid = user.getPos().getId();

        whereSqlList.add(" 1 = 1");
        // 只查询动态
        whereSqlList.add("(ea.act_flag & " + EgActionFlag.DYNAMIC + ")> 0 ");
        // 如果用户在门派,默认查询该门派下所有驿馆的动态
        if (otype.equals(EgOType.FACTION)) {
            whereSqlList.add(" ea.pos_oid IN (SELECT egid FROM eg_tavern WHERE fid = " + oid + ")");
        }
        // 如果用户在驿馆，获取该驿馆所属的门派信息(可能没有所属的门派)，默认查询该门派下所有驿馆的动态
        if (otype.equals(EgOType.TAVERN)) {
            EgTavern tavern = tavernService.getById(oid);
            if (tavern != null) {
                Long fid = tavern.getFaction().getId();
                whereSqlList.add(" ea.pos_oid IN (SELECT egid FROM eg_tavern WHERE fid = " + fid + ")");
            }
        }
        // 如果用户在江湖，查询用户参与的驿馆(江湖驿馆，门派驿馆)
        if (otype.equals(EgOType.JIANGHU)) {
            // 根据用户ID获取其参与的所有驿馆ID列表
            List<Long> taverIds = staffService.taverIdsByUser(uid);
            if (taverIds != null && taverIds.size() > 0) {
                whereSqlList.add(" ea.pos_oid in (" + StringUtils.join(taverIds, ",") + ")");
            }
        }
        // 过滤查询用户的动态列表
        if (id > 0 && buid) {
            whereSqlList.add(" ea.uid = " + id);
        }
        // 过滤查询位置对象中的动态列表
        if (pos != null) {
            // 默认位置对象类型为驿馆,否则按照位置类型的ID查询
            if (pos.getType() == null || pos.getType().getOtid() == null || pos.getType().getOtid() == 0) {
                posOtype = EgOType.TAVERN;
            } else {
                posOtype = pos.getType().getOtid();
            }
            whereSqlList.add(" ea.pos_otype = " + posOtype);
            // 查看门派中驿馆动态时：默认情况分两种：用户有天眼权限，用户没有天眼权限
            if (otype.equals(EgOType.FACTION) || otype.equals(EgOType.TAVERN)) {
                if (pos.getId() == null || pos.getId() == 0) {
                    // 登录用户拥有查看天眼权限，应该查询所有驿馆动态列表；否则，只查询当前用户所在驿馆动态列表
                    if (role != null && (role.getPurview() & EgPurview.STATISTIC_VW) > 0) {
                    } else {
                        List<Long> taverIds = staffService.taverIdsByUser(uid);
                        if (taverIds != null && taverIds.size() > 0) {
                            whereSqlList.add(" ea.pos_oid in (" + StringUtils.join(taverIds, ",") + ")");
                        }
                    }
                } else { // 否则按照位置对象的ID查询
                    posId = pos.getId();
                    whereSqlList.add(" ea.pos_oid = " + posId);
                }
            } else {
                // 查询驿馆江湖中的动态时(按照驿馆筛选)
                if (pos.getId() != null && pos.getId() != 0) {
                    posId = pos.getId();
                    whereSqlList.add(" ea.pos_oid = " + posId);
                }
            }
        }
        // 设置查询条件AND连接符
        if (whereSqlList.size() > 0) {
            whereSql += String.join(" AND ", whereSqlList);
        }
        // 排序规则
        whereSql += " ORDER BY ea.ctime DESC";
        return whereSql;
    }
}
